<template>
    <div class="knob">
        <div class="knob-control" 
             :style="knobStyle" 
             @mousedown="startDrag" 
             @touchstart="startDrag"
             @dblclick="reset"></div>
        <label v-if="false">{{ label }}</label>
    </div>
</template>

<script>
import { defineComponent, ref, computed, watch, onMounted, onUnmounted } from 'vue';

export default defineComponent({
    name: 'Knob',
    props: {
        label: String,
        minAngle: {
            type: Number,
            default: -150
        },
        maxAngle: {
            type: Number,
            default: 150
        },
        initialValue: {
            type: Number,
            default: 0.515
        }
    },
    setup(props, { emit }) {
        const value = ref(props.initialValue);
        const isDragging = ref(false);
        const startY = ref(0);

        const knobImageUrl = computed(() => {
            const publicPath = __webpack_public_path__ || '/';
            return `${publicPath}assets/black.png`;
        });

        const knobStyle = computed(() => {
            const spriteIndex = Math.round(value.value * 100);
            const spriteY = spriteIndex * 120; // Each sprite height is 120 pixels
            return {
                // backgroundImage: `url(${knobImageUrl.value})`,
                backgroundPosition: `0 -${spriteY}px`
            };
        });

        const startDrag = (event) => {
            isDragging.value = true;
            startY.value = event.type.startsWith('touch') ? event.touches[0].clientY : event.clientY;
            document.addEventListener('mousemove', drag);
            document.addEventListener('touchmove', drag, { passive: false });
            document.addEventListener('mouseup', stopDrag);
            document.addEventListener('touchend', stopDrag);
        };

        const drag = (event) => {
            if (!isDragging.value) return;
            event.preventDefault(); // Prevent scrolling on touch devices
            const currentY = event.type.startsWith('touch') ? event.touches[0].clientY : event.clientY;
            const deltaY = startY.value - currentY;
            startY.value = currentY;
            const newValue = value.value + deltaY / 300;
            value.value = Math.min(1, Math.max(0, newValue));
            emit('input', value.value);
        };

        const stopDrag = () => {
            isDragging.value = false;
            document.removeEventListener('mousemove', drag);
            document.removeEventListener('touchmove', drag);
            document.removeEventListener('mouseup', stopDrag);
            document.removeEventListener('touchend', stopDrag);
        };

        const reset = () => {
            value.value = props.initialValue;
            emit('input', value.value);
        };

        watch(value, (newValue) => {
            emit('valueChange', { label: props.label, value: newValue });
        });

        onMounted(() => {
            document.addEventListener('touchmove', preventScroll, { passive: false });
        });

        onUnmounted(() => {
            document.removeEventListener('touchmove', preventScroll);
        });

        const preventScroll = (event) => {
            if (isDragging.value) {
                event.preventDefault();
            }
        };

        return {
            knobStyle,
            startDrag,
            reset
        };
    }
});
</script>

<style scoped>
.knob {
    width: 80px;
    height: 80px;
    text-align: center;
    position: absolute;
    top: 64.5%;
    left: 47%;
}

.knob-control {
    background-image: url('../assets/black.png');
    background-repeat: no-repeat;
    background-size: 120px 12600px;
    width: 120px;
    height: 120px;
    cursor: pointer;
    touch-action: none; /* Prevents default touch actions */
}

label {
    display: none;
}
</style>